package com.devilvan.betrice.service.impl;

import cn.hutool.core.util.StrUtil;
import com.devilvan.betrice.cache.util.URedis;
import com.devilvan.betrice.constant.CacheConstant;
import com.devilvan.betrice.constant.FlagConstant;
import com.devilvan.betrice.constant.OperateModule;
import com.devilvan.betrice.exception.captcha.CaptchaException;
import com.devilvan.betrice.exception.captcha.CaptchaExpireException;
import com.devilvan.betrice.sensitive.event.LoginOperLogEvent;
import com.devilvan.betrice.service.SysConfigService;
import com.devilvan.betrice.service.SysLoginService;
import com.devilvan.betrice.service.SysUserService;
import com.devilvan.betrice.util.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @author Evad.Wu
 * @Description 登录功能 业务逻辑实现类
 * @date 2023-08-12
 */
@Slf4j
@Service
@RequiredArgsConstructor
@SuppressWarnings("SameParameterValue")
public class SysLoginServiceImpl implements SysLoginService {
    private final SysConfigService sysConfigService;
    private final SysUserService sysUserService;

    @Override
    public String login(String username, String password, String code, String uuid) {
        boolean captchaEnabled = sysConfigService.selectCaptchaEnabled();
        if (captchaEnabled) {
            validateCaptcha(username, code, uuid);
        }
//        loadUserByUsername(username);
        return null;
    }

//    private SysUser loadUserByUsername(String username) {
//        SysUserPo sysUserPo = sysUserService.loadUserByUsername(username);
//        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
//                .select(SysUser::getUserName, SysUser::getStatus)
//                .eq(SysUser::getUserName, username));
//        if (ObjectUtil.isNull(user)) {
//            log.info("登录用户：{} 不存在.", username);
//            throw new UserException("user.not.exists", username);
//        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
//            log.info("登录用户：{} 已被停用.", username);
//            throw new UserException("user.blocked", username);
//        }
//        return userMapper.selectUserByUserName(username);
//    }

    /**
     * 校验验证码
     *
     * @param username 用户名
     * @param code     验证码
     * @param uuid     唯一标识
     */
    public void validateCaptcha(String username, String code, String uuid) {
        String verifyKey = CacheConstant.CAPTCHA_CODE_KEY + StrUtil.emptyToDefault(uuid, "");
        String captcha = URedis.get(verifyKey);
        URedis.delete(verifyKey);
        if (captcha == null) {
            recordLoginOperLog(username, UString.upperFirst(FlagConstant.FAILED), UMessage.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            recordLoginOperLog(username, UString.upperFirst(FlagConstant.FAILED), UMessage.message("user.jcaptcha.error"));
            throw new CaptchaException();
        }
    }

    /**
     * 记录敏感操作信息登录信息
     *
     * @param username 用户名
     * @param result   结果
     * @param message  消息内容
     */
    private void recordLoginOperLog(String username, String result, String message) {
        LoginOperLogEvent loginOperLogEvent = new LoginOperLogEvent();
        loginOperLogEvent.setOperatorId(0L);
        loginOperLogEvent.setOperatorName(username);
        loginOperLogEvent.setUrl(UServlet.getRequestUrl());
        loginOperLogEvent.setBeOperatedId(0L);
        loginOperLogEvent.setBeOperatedName(username);
        loginOperLogEvent.setIpAddress(UServlet.getInitiatedRequestIp());
        loginOperLogEvent.setLocation(URegion.getRealAddressByIp(UServlet.getInitiatedRequestIp()));
        loginOperLogEvent.setOperateTime(new Date());
        loginOperLogEvent.setBrowser(UServlet.getBrowser());
        loginOperLogEvent.setOs(UServlet.getOs());
        loginOperLogEvent.setModule(OperateModule.USER_MANAGEMENT);
        loginOperLogEvent.setSubModule(null);
        loginOperLogEvent.setType(OperateModule.LOGIN);
        loginOperLogEvent.setResult(result);
        loginOperLogEvent.setContextOld(null);
        loginOperLogEvent.setContext(null);
        loginOperLogEvent.setSign(username);
        loginOperLogEvent.setRemark(message);
        USpring.context().publishEvent(loginOperLogEvent);
    }
}
